#ifndef MATH_VECTOR
#define MATH_VECTOR

#include "XYZW.hpp"
#include "../shorcut_type.hpp"
#include "StructDataVector.hpp"

#include <iostream>
#include <math.h>

using namespace std;




namespace Math
{
  
  
template <typename T, typename K = T>
class Vector; 

template <typename T, typename K>
const Vector<T,K> operator+(const T* const left, const Vector<T,K>& right);

template <typename T, typename K>
const Vector<T,K> operator*(const K left, const Vector<T,K>& right);



template <typename T, typename K>
class Vector : public StructDataVector<T,K>
    {
        public:
            ~Vector() {} 
            Vector(const Vector<T,K>& copy) : StructDataVector<T,K>(copy) {}
            Vector(Vector<T,K>&& move)      : StructDataVector<T,K>((Vector<T,K>&&)move) {}
            Vector()                        : StructDataVector<T,K>() {}
            Vector(const T* const vec)      : StructDataVector<T,K>() {}
            Vector(T* vec, RC c = RC::COPY) : StructDataVector<T,K>(vec, c) {}
            Vector(T* x, T* y, T* z, T* w, RC c = RC::REF) : StructDataVector<T,K>(x, y, z, w, c) {}
            Vector(T x, T y, T z, T w) : StructDataVector<T,K>(x, y, z, w) {}

            inline T           VcdotV(const Vector<T,K>& vec);
            inline T           VcdotV(const Vector<T,K>* const vec);
            inline Vector<T,K> VxV(const Vector<T,K>& vec);
            inline Vector<T,K> VxV(const Vector<T,K>* const vec);

            inline T    size() const;
                   void LoadZeroVector();
		   
            const Vector<T,K>& operator=(const Vector<T,K>& right);
            const Vector<T,K>& operator=(Vector<T,K>&& right);
            Vector<T,K>        operator+(const Vector<T,K>& right) const;
            Vector<T,K>        operator+(const T* const right) const;
            Vector<T,K>        operator*(const K right) const;

            friend const Vector<T,K> (Math::operator+<>)(const T* const left, const Vector<T,K>& right);
            friend const Vector<T,K> (Math::operator*<>)(const K left, const Vector<T,K>& right);
    }; // end class Vector
} // end namespace Math



#include "error/Throw_Vector.hpp"
#include "OWVector.hpp" 

#include "source/Vector.cpp"



#endif
